package com.hanxiaozhang.io.sockettcp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

/**
 * 〈一句话功能简述〉<br>
 * 〈使用Socket演示Tcp三次握手〉
 * <p>
 * Tips：三次握手发送在内核态，操作系统去执行握手操作。
 *      以下演示的程序，已经完成了三次握手，在用户态发送数据了。
 *
 * @author hanxinghua
 * @create 2023/5/31
 * @since 1.0.0
 */
public class TcpServer {

    private static final int PORT = 56002;

    public static void main(String[] args) {
        ServerSocket ss = null;
        try {
            // 创建一个服务器 Socket
            ss = new ServerSocket(PORT);
            // 监听新连接请求，阻塞获取
            Socket conn = ss.accept();
            System.out.println("Accept a new connection: " + conn.getRemoteSocketAddress().toString());

            // 读取客户端数据 client ACK
            String msg = TcpUtil.receiveMsg(conn);
            System.out.println("Server Recv from client: " + msg);

            // 向客户端发送数据  server ACK + SYN
            String req = "SYN seq 3824468340 ACK ack 543067662";
            TcpUtil.sendMsg(conn, req);
            System.out.println("Server Send to client: " + req);

            // 读取客户端数据 client ACK
            msg = TcpUtil.receiveMsg(conn);
            System.out.println("Server Recv from client: " + msg);

            // ---- 通信  ----
            msg = TcpUtil.receiveMsg(conn);
            System.out.println("Server Recv from client: " + msg);

            req = "Hello,Nice to meet you too";
            TcpUtil.sendMsg(conn, req);
            System.out.println("Server Send to client: " + req);

            // ---- 关闭链接 ----
            req = "see you";
            TcpUtil.sendMsg(conn, req);
            System.out.println("Server Send to client: " + req);
            TimeUnit.SECONDS.sleep(1);
            conn.close();

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        System.out.println("Server exit!");
    }

}
